package cn.xzc.job;


import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;

/**
 * 定时任务调度器,根据不同的触发器对runnable执行
 *
 * @author xzc
 * 当前时间 2024-02-12 21:30:00
 */
public interface JobScheduler {

    /**
     * Return the clock to use for scheduling purposes.
     * 获取当前定时任务的clock
     */
    default Clock getClock() {
        return Clock.systemDefaultZone();
    }

    /**
     * Schedule the given {@link Runnable}, invoking it whenever the trigger indicates a next execution time.
     * 根据触发器获取下一次runnable执行的时间
     * Execution will end once the scheduler shuts down or the returned gets cancelled.
     * 任务执行结束后，如果任务还在运行，则会被关闭
     *
     * @param job     the Runnable to execute whenever the trigger fires 根据触发器执行runnable
     * @param trigger 触发器【获取下次runnable执行时间】
     * @return ScheduledFuture
     */
    ScheduledFuture<?> schedule(Runnable job, Trigger trigger);

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time.
     * 根据startTime执行runnable
     *
     * @param job       the Runnable to execute whenever the trigger fires 根据触发器执行runnable
     * @param startTime the desired execution time for the job 下次runnable执行的时间【当now大于当前startTime值时，runnable会立刻执行】
     * @return ScheduledFuture
     */
    default ScheduledFuture<?> schedule(Runnable job, Instant startTime) {
        return schedule(job, Date.from(startTime));
    }

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time.
     * 根据startTime执行runnable
     *
     * @param job       the Runnable to execute whenever the trigger fires 根据触发器执行runnable
     * @param startTime the desired execution time for the job 任务执行时间【当now大于当前startTime值时，runnable会立刻执行】
     * @return ScheduledFuture
     */
    ScheduledFuture<?> schedule(Runnable job, Date startTime);

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time and subsequently with the given period.
     * 任务每隔period时间执行一次【间隔时间计算以上一次任务开始时间计算】
     *
     * @param job       the Runnable to execute whenever the trigger fires 根据触发器执行runnable
     * @param startTime the desired first execution time for the job 任务第一次执行时间【当now大于当前startTime值时，第一次执行runnable会立刻执行】
     * @param period    the interval between successive executions of the job 任务执行的间隔时间
     * @return ScheduledFuture
     */
    default ScheduledFuture<?> scheduleAtFixedRate(Runnable job, Instant startTime, Duration period) {
        return scheduleAtFixedRate(job, Date.from(startTime), period.toMillis());
    }

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time and subsequently with the given period.
     * 任务每隔period时间执行一次【间隔时间计算以上一次任务开始时间计算】
     *
     * @param job       the Runnable to execute whenever the trigger fires 根据触发器执行runnable
     * @param startTime the desired first execution time for the job 任务第一次执行时间【当now大于当前startTime值时，第一次执行runnable会立刻执行】
     * @param period    the interval between successive executions of the job (in milliseconds) 任务执行的间隔时间
     * @return ScheduledFuture
     */
    ScheduledFuture<?> scheduleAtFixedRate(Runnable job, Date startTime, long period);

    /**
     * Schedule the given {@link Runnable}, starting as soon as possible and invoking it with the given period.
     * 任务每隔period时间执行一次【间隔时间计算以上一次任务开始时间计算】
     *
     * @param job    the Runnable to execute whenever the trigger fires
     * @param period the interval between successive executions of the job 任务执行的间隔时间
     * @return ScheduledFuture
     */
    default ScheduledFuture<?> scheduleAtFixedRate(Runnable job, Duration period) {
        return scheduleAtFixedRate(job, period.toMillis());
    }

    /**
     * Schedule the given {@link Runnable}, starting as soon as possible and invoking it with the given period.
     * 任务每隔period时间执行一次【间隔时间计算以上一次任务开始时间计算】
     *
     * @param job    the Runnable to execute whenever the trigger fires
     * @param period the interval between successive executions of the job (in milliseconds) 任务执行的间隔时间
     * @return ScheduledFuture
     */
    ScheduledFuture<?> scheduleAtFixedRate(Runnable job, long period);

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time and subsequently with the given delay between the completion of one execution and the start of the next.
     * 任务每隔delay时间执行一次 【间隔时间计算以上一次任务结束时间计算】
     *
     * @param job       the Runnable to execute whenever the trigger fires
     * @param startTime the desired first execution time for the job 任务第一次执行时间【当now大于当前startTime值时，第一次执行runnable会立刻执行】
     * @param delay     the delay between the completion of one execution and the start of the next 任务执行的间隔时间【间隔时间计算以上一次任务结束时间计算】
     * @return ScheduledFuture
     */
    default ScheduledFuture<?> scheduleWithFixedDelay(Runnable job, Instant startTime, Duration delay) {
        return scheduleWithFixedDelay(job, Date.from(startTime), delay.toMillis());
    }

    /**
     * Schedule the given {@link Runnable}, invoking it at the specified execution time and subsequently with the given delay between the completion of one execution and the start of the next.
     * 任务每隔delay时间执行一次 【间隔时间计算以上一次任务结束时间计算】
     *
     * @param job       the Runnable to execute whenever the trigger fires
     * @param startTime the desired first execution time for the job 任务第一次执行时间【当now大于当前startTime值时，第一次执行runnable会立刻执行】
     * @param delay     the delay between the completion of one execution and the start of the next 任务执行的间隔时间【 间隔时间计算以上一次任务结束时间计算】
     * @return ScheduledFuture
     */
    ScheduledFuture<?> scheduleWithFixedDelay(Runnable job, Date startTime, long delay);

    /**
     * Schedule the given {@link Runnable}, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next.
     * 任务每隔delay时间执行一次 【间隔时间计算以上一次任务结束时间计算】
     *
     * @param job   the Runnable to execute whenever the trigger fires
     * @param delay the delay between the completion of one execution and the start of the next 任务执行的间隔时间【间隔时间计算以上一次任务结束时间计算】
     * @return ScheduledFuture
     */
    default ScheduledFuture<?> scheduleWithFixedDelay(Runnable job, Duration delay) {
        return scheduleWithFixedDelay(job, delay.toMillis());
    }

    /**
     * Schedule the given {@link Runnable}, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next.
     * 任务每隔delay时间执行一次 【间隔时间计算以上一次任务结束时间计算】
     *
     * @param job   the Runnable to execute whenever the trigger fires
     * @param delay the delay between the completion of one execution and the start of the next 任务执行的间隔时间【间隔时间计算以上一次任务结束时间计算】
     * @return ScheduledFuture
     */
    ScheduledFuture<?> scheduleWithFixedDelay(Runnable job, long delay);

}
